<template>
  <a-menu
    :theme="theme"
    :mode="mode"
    :open-keys="openKeys"
    :selected-keys="selectedKeys"
    v-bind="dynamicProps"
    @open-change="handleOpenChange"
    @select="handleSelect"
    @mouseenter="$emit('mouseenter', $event)"
    @mouseleave="$emit('mouseleave', $event)"
  >
    <template v-for="menu in menus">
      <transform-vnode
        v-if="(!menu.children || menu.meta?.hideChildrenInMenu) && !menu.meta?.hideInMenu"
        :key="menu.path"
        :by="customItem"
        :opt="menu"
      >
        <a-menu-item :key="menu.path" @mouseenter="$emit('itemHover', { key: menu.path })">
          <template #icon>
            <template v-if="menu.meta.icon !== undefined">
              <component :is="menu.meta.icon" />
            </template>
            <template v-else-if="collapsed && menu.meta.collapsedIcon !== undefined">
              <component :is="menu.meta.collapsedIcon" />
            </template>
          </template>
          {{ $t(menu.meta.title) }}
        </a-menu-item>
      </transform-vnode>
      <template v-else-if="menu.children">
        <sub-menu
          :key="menu.path"
          :menu="menu"
          :collapsed="collapsed"
          @item-hover="$emit('itemHover', $event)"
        />
      </template>
    </template>
  </a-menu>
</template>
<script lang="ts">
export const BaseMenuProps = {
  locale: {
    type: Boolean,
    default: false,
  },
  menus: {
    type: Array as PropType<RouteProps[]>,
    required: true,
  },
  // top-nav-header: horizontal
  mode: {
    type: String as PropType<MenuProps['mode']>,
    default: 'inline',
  },
  theme: {
    type: String as PropType<MenuTheme>,
    default: 'dark',
  },
  collapsed: {
    type: Boolean,
    default: false,
  },
  openKeys: {
    type: Array as PropType<string[]>,
    required: true,
  },
  selectedKeys: {
    type: Array as PropType<string[]>,
    required: true,
  },
  customItem: {
    type: Function,
    default: undefined,
  },
  underSider: Boolean,
};
</script>
<script setup lang="ts">
import type { MenuProps, MenuTheme } from 'ant-design-vue';
import type { PropType } from 'vue';
import { computed } from 'vue';
import type { RouteProps } from '../typing';
import SubMenu from './sub-menu.vue';

const props = defineProps(BaseMenuProps);

const emit = defineEmits([
  'update:openKeys',
  'update:selectedKeys',
  'mouseenter',
  'mouseleave',
  'itemHover',
]);

const isInline = computed(() => props.mode === 'inline');

const dynamicProps = computed(() => {
  return isInline.value
    ? { [props.underSider ? 'collapsed' : 'inlineCollapsed']: props.collapsed }
    : {};
});

const handleOpenChange = (openKeys: string[]): void => {
  emit('update:openKeys', openKeys);
};

const handleSelect = (ctx: { [key: string]: any }): void => {
  emit('update:selectedKeys', ctx.selectedKeys);
};
</script>
